package com.hcc.repository.gen.model;

import com.hcc.repository.core.utils.CollUtils;
import com.hcc.repository.core.utils.StrUtils;
import com.hcc.repository.gen.config.ControllerConfig;
import com.hcc.repository.gen.config.EntityConfig;
import com.hcc.repository.gen.config.GlobalConfig;
import com.hcc.repository.gen.config.MapperConfig;
import com.hcc.repository.gen.config.RepositoryConfig;
import com.hcc.repository.gen.config.RepositoryImplConfig;
import com.hcc.repository.gen.config.ServiceConfig;
import com.hcc.repository.gen.config.ServiceImplConfig;
import lombok.Data;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TableMetadata
 *
 * @author hushengjun
 * @date 2023/9/20
 */
@Data
public class TableMetadata {

    private String name;
    private String comment;
    private List<ColumnMetadata> columns;
    private GlobalConfig globalConfig;

    public String getComment() {
        if (StrUtils.isEmpty(comment)) {
            return name;
        }
        return comment;
    }

    public String getEntityName() {
        String entityName = StrUtils.underlineToHump(name);
        if (StrUtils.isEmpty(entityName)) {
            throw new IllegalArgumentException(String.format("无法将表名：[%s]转换为驼峰", name));
        }
        return entityName;
    }

    public String getPropName() {
        return StrUtils.firstCharToLowerCase(getEntityName());
    }

    public String getEntityClassName() {
        EntityConfig entityConfig = globalConfig.getEntityConfig();
        return entityConfig.getPrefix()
                + getEntityName()
                + entityConfig.getSuffix();
    }

    public String getMapperClassName() {
        MapperConfig mapperConfig = globalConfig.getMapperConfig();
        return mapperConfig.getPrefix()
                + getEntityName()
                + mapperConfig.getSuffix();
    }

    public String getRepositoryClassName() {
        RepositoryConfig repositoryConfig = globalConfig.getRepositoryConfig();
        return repositoryConfig.getPrefix()
                + getEntityName()
                + repositoryConfig.getSuffix();
    }

    public String getRepositoryImplClassName() {
        RepositoryImplConfig repositoryImplConfig = globalConfig.getRepositoryImplConfig();
        return repositoryImplConfig.getPrefix()
                + getEntityName()
                + repositoryImplConfig.getSuffix();
    }

    public String getServiceClassName() {
        ServiceConfig serviceConfig = globalConfig.getServiceConfig();
        return serviceConfig.getPrefix()
                + getEntityName()
                + serviceConfig.getSuffix();
    }

    public String getServiceImplClassName() {
        ServiceImplConfig serviceImplConfig = globalConfig.getServiceImplConfig();
        return serviceImplConfig.getPrefix()
                + getEntityName()
                + serviceImplConfig.getSuffix();
    }

    public String getControllerClassName() {
        ControllerConfig controllerConfig = globalConfig.getControllerConfig();
        return controllerConfig.getPrefix()
                + getEntityName()
                + controllerConfig.getSuffix();
    }

    /**
     * 是否需要注解标注
     * @return
     */
    public boolean needAnnotated() {
        if (StrUtils.isNotEmpty(globalConfig.getEntityConfig().getSuffix())
                || StrUtils.isNotEmpty(globalConfig.getEntityConfig().getPrefix())) {
            return true;
        }
        if (globalConfig.getEntityConfig().isEnableLombok()) {
            return true;
        }
        return name.startsWith("_") || name.endsWith("_");
    }

    public List<String> getAnnotations() {
        List<String> annotations = new ArrayList<>();
        if (globalConfig.getEntityConfig().isEnableLombok()) {
            annotations.add("@Data");
        }
        if (needAnnotated()) {
            annotations.add("@Table(value = \"" + name + "\")");
        }

        return annotations;
    }

    public List<String> getImportPackages() {
        List<String> importPackages = new ArrayList<>();
        if (this.needAnnotated()) {
            importPackages.add("com.hcc.repository.annotation.Table");
        }

        importPackages.addAll(
                this.getColumns().stream()
                .map(ColumnMetadata::getPropImportPackage)
                .filter(StrUtils::isNotEmpty)
                .collect(Collectors.toList())
        );

        importPackages.addAll(
                this.getColumns().stream()
                        .map(ColumnMetadata::getAnnotationImportPackage)
                        .filter(CollUtils::isNotEmpty)
                        .flatMap(Collection::stream)
                        .collect(Collectors.toList())
        );

        return importPackages.stream()
                .distinct()
                .filter(p -> !p.startsWith("java.lang"))
                .collect(Collectors.toList());
    }

    public String getIdImportPackage() {
        String pkg = columns.stream()
                .filter(ColumnMetadata::isPrimary)
                .findFirst()
                .map(c -> c.getJavaType().getName())
                .orElse("java.io.Serializable");
        if (pkg.startsWith("java.lang")) {
            return null;
        }
        return pkg;
    }

    public String getIdClassName() {
        return columns.stream()
                .filter(ColumnMetadata::isPrimary)
                .findFirst()
                .map(c -> c.getJavaType().getSimpleName())
                .orElse("Serializable");
    }

    public List<ColumnMetadata> getColumns() {
        EntityConfig entityConfig = globalConfig.getEntityConfig();
        List<String> superEntityColumns = entityConfig.getSuperEntityColumns();
        if (entityConfig.getSuperClass() == null || CollUtils.isEmpty(superEntityColumns)) {
            return columns;
        }
        return columns.stream()
                .filter(c -> !superEntityColumns.contains(c.getName()))
                .collect(Collectors.toList());
    }
}
